package com.example.daxiguaforharmony.game.core;

import com.example.daxiguaforharmony.game.GameScene;
import com.example.daxiguaforharmony.game.core.base.DisplayObjectContainer;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.Fixture;

public class GameRenderTask implements Component.DrawTask {
    private GameScene _scene = null;
    private Paint _paint = null;
    private float _sceneWidth = 1080;
    private float _sceneHeight = 2400;
    private RectFloat _renderRect = null;
    private DisplayObjectContainer _container = null;
    private boolean _debug = false;
    private Color _bgColor = null;

    public GameRenderTask() {
        this._paint = new Paint();
        this._renderRect = new RectFloat(0,0, this._sceneWidth, this._sceneHeight);
        this._bgColor = new Color(Color.rgb(255, 232, 157));
        this._debug = false;
    }

    public void initScene(GameScene scene) {
        this._scene = scene;
        this._sceneWidth = scene.getSceneWidth();
        this._sceneHeight = scene.getSceneHeight();
        this._renderRect.right = this._sceneWidth;
        this._renderRect.bottom = this._sceneHeight;
        this._container = scene.getDisplayContainer();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        Paint paint = this._paint;
        paint.setColor(this._bgColor);
        canvas.drawRect(this._renderRect, paint);
        if (this._debug) this.drawWorld(canvas, paint);
        if (this._container != null) this._container.render(canvas, paint);
    }

    private void drawWorld(Canvas canvas, Paint paint) {
        if (this._scene == null) return;
        Body body = this._scene.world.getBodyList();
        for (Body b = body; b != null; b = b.getNext())
        {
            for (Fixture f = b.getFixtureList(); f != null; f = f.getNext()) {
                if (b.isActive() == false) {
                    paint.setColor(Color.BLUE);
                    this.drawShape(b, f, canvas, paint);
                } else if (b.getType() == BodyType.STATIC) {
                    paint.setColor(Color.RED);
                    this.drawShape(b, f, canvas, paint);
                } else if (b.getType() == BodyType.KINEMATIC) {
                    paint.setColor(Color.BLUE);
                    this.drawShape(b, f, canvas, paint);
                } else if (b.isAwake() == false) {
                    paint.setColor(Color.LTGRAY);
                    this.drawShape(b, f, canvas, paint);
                } else {
                    paint.setColor(Color.GREEN);
                    this.drawShape(b, f, canvas, paint);
                }
            }
        }
    }

    private void drawShape(Body body, Fixture fixture, Canvas canvas, Paint paint) {
        switch (fixture.getType()) {
            case CIRCLE: {
                CircleShape circle = (CircleShape)fixture.getShape();
                if (circle.m_radius <= 0) break;
                float radius = circle.m_radius * GameScene.RATE;
                Vec2 pos = body.getPosition();
                canvas.drawCircle((pos.x + circle.m_p.x) * GameScene.RATE, (pos.y + circle.m_p.y) * GameScene.RATE, radius, paint);
            } break;
            case POLYGON: {
                PolygonShape shape = (PolygonShape)fixture.getShape();
                Vec2[] vecs = shape.getVertices();
                Vec2 pos = body.getPosition();
                RectFloat rect = new RectFloat((pos.x + vecs[0].x) * GameScene.RATE, (pos.y + vecs[0].y) * GameScene.RATE,
                        (pos.x + vecs[2].x) * GameScene.RATE, (pos.y + vecs[2].y) * GameScene.RATE);
                canvas.drawRect(rect, paint);
            } break;
        }
    }
}
